package org.radargun.stats;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.radargun.Operation;
import org.radargun.utils.TimeService;
/**
* Tracks time for RPC-like operations, possibly asynchronous (TODO).
* @see Message for tracking messages with different origin and destination.
*
* @author Radim Vansa <rvansa@redhat.com>
*/
public final class Request {
private final Statistics statistics;
private final long requestStartTime;
// This is for async:
// private long requestCompleteTime;
// private long responseStartedTime;
private long responseCompleteTime = Long.MIN_VALUE;
private boolean successful = true;
public Request(Statistics statistics) {
this.statistics = statistics;
this.requestStartTime = TimeService.nanoTime();
}
public void exec(Operation operation, Runnable runnable) {
try {
runnable.run();
succeeded(operation);
} catch (Throwable t) {
failed(operation);
throw t;
}
}
public <T> T exec(Operation operation, Supplier<T> supplier) {
try {
T value = supplier.get();
succeeded(operation);
return value;
} catch (Throwable t) {
failed(operation);
throw t;
}
}
public <T> T exec(Operation operation, Supplier<T> supplier, Predicate<T> predicate) {
T value;
try {
value = supplier.get();
} catch (Throwable t) {
failed(operation);
throw t;
}
responseCompleteTime = TimeService.nanoTime();
try {
successful = predicate.test(value);
} catch (Throwable t) {
successful = false;
throw t;
} finally {
statistics.record(this, operation);
}
return value;
}
// This is for async:
// public void requestCompleted() {}
// public void requestFailed() {}
// public void responseStarted() {}
public void succeeded(Operation operation) {
this.responseCompleteTime = TimeService.nanoTime();
statistics.record(this, operation);
}
public void failed(Operation operation) {
this.responseCompleteTime = TimeService.nanoTime();
this.successful = false;
statistics.record(this, operation);
}
public void discard() {
statistics.discard(this);
}
public boolean isSuccessful() {
return successful;
}
public boolean isFinished() {
return responseCompleteTime > Long.MIN_VALUE;
}
public long getRequestStartTime() {
return requestStartTime;
}
public long getResponseCompleteTime() {
return responseCompleteTime;
}
/**
* @return Total duration in nanoseconds.
*/
public long duration() {
return responseCompleteTime - requestStartTime;
}
}